package com.es.array;

/**
 * @author 二十
 */
public class DynamicArray<T> extends AbstractArray<T> {

    private T[] objs;

    private int size;

    public DynamicArray() {
        objs = (T[]) new Object[10];
    }

    public DynamicArray(int size) {
        objs = (T[]) new Object[size];
    }

    @Override
    public int getSize() {
        return size;
    }

    @Override
    public int getCapacity() {
        return objs.length;
    }

    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    @Override
    public void addIndex(T data, int index) {
        if (index < 0 | index > size) {
            throw new IllegalArgumentException("index error");
        }

        if (size == objs.length) {
            resize(objs.length * 2);
        }

        for (int i = size - 1; i >=index; i--) {
            objs[i+1] = objs[i];
        }
        objs[index] = data;
        size++;
    }

    @Override
    public void addFirst(T data) {
        addIndex(data, 0);
    }

    @Override
    public void addLast(T data) {
        addIndex(data, size);
    }


    @Override
    public T deleteIndex(int index) {
        if (index < 0 | index > size) {
            throw new IllegalArgumentException("index error");
        }
        T ret = objs[index];

        for (int i = index; i < size - 1; i++) {
            objs[i] = objs[i + 1];
        }
        size--;
        if (size * 4 == objs.length && objs.length / 2 > 0) {
            resize(objs.length / 2);
        }
        return ret;
    }

    @Override
    public T deleteFirst() {
        return deleteIndex(0);
    }

    @Override
    public T deleteLast() {
        return deleteIndex(size - 1);
    }

    @Override
    public T get(int index) {
        if (index < 0 | index > size) {
            throw new IllegalArgumentException("index error");
        }
        return objs[index];
    }

    @Override
    public void set(T data, int index) {
        if (index < 0 | index > size) {
            throw new IllegalArgumentException("index error");
        }
        objs[index] = data;
    }

    @Override
    public boolean contains(T data) {


        for (int i = 0; i < size; i++) {
            if ((data == null && objs[i] == null) || objs[i].equals(data)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public int find(T data) {

        for (int i = 0; i < size; i++) {
            if ((data == null && objs[i] == null) || objs[i].equals(data)) {
                return i;
            }
        }
        return -1;
    }

    @Override
    public void clear() {
        objs = null;
        size = 0;
    }


    /**
     * 扩容 需要子类显式重写
     *
     * @param capacity
     */
    @Override
    protected void resize(int capacity) {
        super.resize(capacity);
        T[] tmp = (T[]) new Object[capacity];

        for (int i = 0; i < size; i++) {
            tmp[i] = objs[i];
            objs[i] = null;
        }
        objs = tmp;
    }

    /**
     * 遍历输出数组中的所有元素
     *
     * @return
     */
    @Override
    public String toString() {

        StringBuilder sb = new StringBuilder("Array:[");

        for (int i = 0; i < size; i++) {
            sb.append(objs[i]);
            if (i != size - 1) {
                sb.append(",");
            }
        }
        return sb.append("]").toString();
    }
}
